{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(24840, 6211)"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import json\n",
    "\n",
    "with open('train-test-rumi-to-jawi.json') as fopen:\n",
    "    dataset = json.load(fopen)\n",
    "len(dataset['train']), len(dataset['test'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('train-test-wiki.json') as fopen:\n",
    "    dataset_wiki = json.load(fopen)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(64840, 16211)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset['train'] = dataset['train'] + dataset_wiki['train']\n",
    "dataset['test'] = dataset['test'] + dataset_wiki['test']\n",
    "len(dataset['train']), len(dataset['test'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "from skimage.transform import resize as imresize\n",
    "import cv2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_labels = [f.split('/')[1].split('.')[0].lower() for f in dataset['train']]\n",
    "test_labels = [f.split('/')[1].split('.')[0].lower() for f in dataset['test']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(cv2.imread(dataset['train'][-1], 0).astype(np.float32)/255.)\n",
    "plt.title(train_labels[-1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "image_height = 60\n",
    "image_width = 240\n",
    "image_channel = 1\n",
    "max_stepsize = 128\n",
    "num_hidden = 256\n",
    "epoch = 20\n",
    "batch_size = 128\n",
    "initial_learning_rate = 1e-3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.ndimage.interpolation import map_coordinates\n",
    "from scipy.ndimage.filters import gaussian_filter\n",
    "\n",
    "def elastic_transform(image, alpha, sigma, alpha_affine, random_state=None):\n",
    "    if random_state is None:\n",
    "        random_state = np.random.RandomState(None)\n",
    "\n",
    "    shape = image.shape\n",
    "    shape_size = shape[:2]\n",
    "    \n",
    "    blur_size = int(4*sigma) | 1\n",
    "    dx = alpha * cv2.GaussianBlur((random_state.rand(*shape) * 2 - 1),\n",
    "                                  ksize=(blur_size, blur_size),\n",
    "                                  sigmaX=sigma)\n",
    "    dy = alpha * cv2.GaussianBlur((random_state.rand(*shape) * 2 - 1),\n",
    "                                  ksize=(blur_size, blur_size),\n",
    "                                  sigmaX=sigma)\n",
    "\n",
    "    x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]))\n",
    "    indices = np.reshape(y+dy, (-1, 1)), np.reshape(x+dx, (-1, 1))\n",
    "\n",
    "    image =  map_coordinates(image, indices, order=1, mode='constant').reshape(shape)\n",
    "    \n",
    "    # Random affine\n",
    "    center_square = np.float32(shape_size) // 2\n",
    "    square_size = min(shape_size) // 4\n",
    "    pts1 = np.float32([center_square + square_size,\n",
    "                       [center_square[0]+square_size, \n",
    "                        center_square[1]-square_size],\n",
    "                       center_square - square_size])\n",
    "    pts2 = pts1 + random_state.uniform(-alpha_affine, alpha_affine, size=pts1.shape).astype(np.float32)\n",
    "    M = cv2.getAffineTransform(pts1, pts2)\n",
    "    image = cv2.warpAffine(image, M, shape_size[::-1], borderMode=cv2.BORDER_CONSTANT)\n",
    "\n",
    "    return image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAACDCAYAAACUaEA8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO29eXRc1ZXv/zlVKpXm0ZIsz4NkeQKDY7AdMBgIs7GBMMRh7qShO8N7rLy3kk6/3/o9fv3rgWZl6KR/L8lKQ7pp4gABAzbEBsdusMGzjSd5tjzLmizJmqVSVZ3fH7fO5pbQbFlS2eezlpZqvPfcU/fuu88+372P0lpjsVgsltjDM9QNsFgsFkv/sAbcYrFYYhRrwC0WiyVGsQbcYrFYYhRrwC0WiyVGsQbcYrFYYhRrwC0xi1JqnFKqUSnlHeq2XCxKqf1KqYWRxy8opX4/xE2yxABxQ90Ai6W/aK1PAylD3Y6+opT6D+Cs1vr/Mq9prWcMXYsssYr1wC2WAUQpZZ0iy6BhDbhlUFBK/Y1SqkQp1aCUOqCUeiDy+tNKqc+UUj9RStUqpU4ope52fW+iUmpD5HtrlVL/x4QXlFITlFLaGE2l1Cil1EqlVI1S6phS6i9d23lBKfVHpdR/Rra1Xyk1x/X+KKXUcqVUVaQN/8313n8opf7e9XyhUuqs6/lJpdSPlFJ7gSalVJxSappS6hOl1IXIvhZHPvss8Bjww0j4533XNr7WSb/5lFKvR9oWPwA/heUywhpwy2BRAiwA0oH/B/i9Uio/8t5c4DAwAngJeEUppSLv/QHYBmQDLwBPdLOPN4CzwCjgIeAflVK3ut5fHPlMBrAS+P8AlFIe4H1gDzAauA14Xil1Zx+Obylwb2TbKrK9NUAu8H1gmVKqSGv9W2AZ8JLWOkVrfV9XG1RKJQLvAW3AI1rrQB/aY7kCsAbcMihord/SWp/TWoe11m8CR4HrI2+f0lr/m9Y6BLwK5AN5SqlxwHXA/621DmitP8MxvF9CKTUWuAH4kda6VWu9G3gZeNL1sc+01qsi+3kNmBV5/TogR2v9d5H9HAf+DfhGHw7xl1rrM1rrFmAeTmz+xcj2/gv4AMfI95Y04EOcG98zkTZbLFHYeJ1lUFBKPQn8AJgQeSkFx+MOAeXmc1rr5ojzbd6v0Vo3uzZ1BhjbyS5GRT7b4HrtFDDH9bzc9bgZSIiEX8YDo5RSF1zve4FPe3t8kXa523JGax3u0JbRfdjePMAHLNW24pylC6wBt1xylFLjcTza24DNWuuQUmo3TqihO8qALKVUksuId2a8Ac5FPpvqMuLjgNJeNPEMcEJrXdjF+01Akuv5yE4+4zay54CxSimPy4iPA4508tmuWAPsBdYppRZqrSt68R3LFYYNoVgGg2Qco1UFoJR6BpjZ05e01qeAHcALSql4pdR8oNOYsdb6DLAJ+CelVIJS6mrgW0Bv9NTbgIbIRGSiUsqrlJqplLou8v5u4B6lVJZSaiTwfA/b24rj4f8wMgm5MNLuNyLvVwCTemqU1volnDmAdUqpEb04DssVhjXglkuO1voA8FNgM47xugrY2MuvPwbMB6qBvwfexJnU64ylOCGac8C7wP/WWq/tRftCwCLgGuAEcB4nfp4e+chrOBOcJ3E84zd72F4Ax2DfHdnWr4AntdaHIh95BZgeUai818O2/l+cicy1Sqmsno7FcmWhbHjNEksopd4EDmmt//dQt8ViGWqsB24Z1iilrlNKTVZKeZRSdwFLcDxSi+WKx05iWoY7I4F3cHTgZ4G/1lrvGtomWSzDg4sKoUQ8ol/gSK5e1lq/OFANs1gsFkv39NuARyrAHQFux/GMtuNoVg8MXPMsFovF0hUXEwO/HjimtT4emXV/Ayc+abFYLJZB4GJi4KOJzj47i1PTokuUUv2O15jSGCNGjCA7OxuAsrIy6uvruRRKGq/XKTGdkZFBZmYmPp8PgNraWmprawFoa+tKzWaxWCwDynmtdU7HFy/5JGak+tqzF7udzMxMAP72b/+Wxx57DIDvfe97rFixYsAM6Rf1k2DChAkA/OpXv2L+/PkkJiYCcOjQIf7xH/8RgNWrV1NXV3dJbiB9RSlFUVER5eVOtnh9fT3hcLiHb1kslhjhVGcvXowBLyU6rXkMnaQtR6qv/RYuzgO3WCwWSzQXY8C3A4VKqYk4hvsbwDcHpFWdEB/vlEL2er3i8Xq93iiveaBIS0sTr37r1q0UFhaSlpYGwMqVK9m3bx8ALS0tw8L7BscDnzt3LseOHQNg7969NDY2AgybNlosloGl3wZcax1USn0P+AhHRvg7rfX+AWtZBzwej9mvvJaUlNTVx/tFRkYGAA8++KCEHz788ENaWlpobW0F4M9//rO0ZezYsZw+fZpAYOjLNHs8HsaMGUNBQQEATU1NFBcXAxAMBoeyaRaL5RJxUTFwrfUqYNUAtcVisVgsfSDmMjHj4uLEO05MTByw8EBSUhL33nsvAE8//TR5eXkAvPnmm7z//vucPn0agJtuuokHHngAgPb2dl599VU2bdoEOCGVocLj8ZCQkMCCBQsAOHv2LCUlJQA0NDR091WLxRKjxIwBNzHwzMxMCVm0tbUNmAFPSEhg9uzZABQVFYnq5Zvf/Cbnz59n6tSpADz88MPMneuoJcPhMM3NzVRXVwOwb98+QqGhWTjF6/WSkZHBxIkTASgoKCA93Smm19jYaOPgFstlSMwY8NGjncVMJkyYQFVVFQAnT54cMIPZ0tLCtm3bALj11lupr68HYNWqVWzevJlJk5zyzTk5OaSmpgJQU1NDSUmJGPChNJIpKSmMHz9e4vjhcBi/3w84E5zWgFsslx+2GqHFYrHEKDHjgSckJACQlZUlySoDGXNubW1lzZo1APj9ftnf+vXrOXXqFEeOOKthJScnc9tttwFQWlrK+++/T2VlJcCQJs6kpqaSkpIiCpnW1lba29uHrD3DFTsasVxOxIQBV0qJcUxISBDDNJDyOK21pMi/++67oi9vamoiFAqJLnzFihVs3bpVvnPy5MlhISNMSkqK0siHw2ErH3Rhbmzp6emEQiHRyNtsVUssY0MoFovFEqPEhAfu8XhkstIUmQLHexrI4bDZlpnA7Oy9mpoa6urqAGdk0N7ePiyG5AkJCVEjFa/XK4+HQ/uGGnPeFBUVobWWJKfm5mbbP5aYJSYMuJHIAfh8PjGwTU1Ng96WcDg8LIfdGRkZJCUlSduam5ttDNxFXJxzqk+ePJnc3FxRDp08edKGmiwxS0wYcPhiwlIpJZUBL0UdlFjD9IEpd2u8Sb/fL4+th/lFDDw1NZUbbrhBJsIrKipsopMlZrExcIvFYolRYsID93q9ZGVlyWMTg25tbb0k3qU7XX84hkvcuBe6SElJkbBJfX29DaG4MKO2zMxMioqKmDNnDuDIRG2mqiVWiRkDnpKSIo+bm5sBBsxAKaXw+/2MHDkScIyhkRSarMsLFy7IfxN7DwaDQ37hGwOenJyM3++XqoktLS1DHtt1h3e01tKeoegzo+tPT08nIyOD/Px8ed1qwy2xig2hWCwWS4wSEx641lqSZUzVPbj4SUxTICsvL4+CggIefPBBAObNmyeql6amJurr60W1cP78efbvd8qef/LJJxw+fLjfGaGm/QPh/Rk543BZp1MpJf07ceJE7rzzTtauXQtASUmJtHOwPF+zn8TERLxer9SSH6riYxbLQBBzBtyEO+ALZUF/8Pv9XHPNNYBTvGr+/Pnk5uYCjmE3Bnzs2LHSBnAMpQmn3Hrrrbz77rv86U9/AqCqqmrIhuJKqajw0lDrmxMSErj22msB+P73v8/8+fOZP38+4Kwzun37dmDwSvCam/6IESOi9jtcdPwWS3+ICQOemJjIqFGj5LmpRngx3mZaWprEQYPBIJs3b5aaJoFAQJZQS01NJT8/X8q0Tp06VWqF33TTTaSnp4vR/PDDD2WCtS/4fL6oSdO+GBTjxefk5JCQkEBFRQUA586dGxLv0rQnKyuL66+/HoD58+czevRoqSFz9OhRDhw4AFy6iWg3Ho+H7OxsAHJzcwkEAlG/tTXglljFxsAtFoslRokJDzwYDIq6QiklihSTXdcf6uvrWb9+PQCffvop4XBYwjRaa/EkPR4PKSkpImPMzc1l5syZANxxxx3MmTOHv/zLv5TvrVixAujd6MCkd8+dO1dGFcePH++Tusad/h8MBkXpMVSepdlndXW1VHe8/vrrWbBgASdPngScKo6DmYSllJL9JSUlRYXkbAzcEsv0aAGVUmOB/wTyAA38Vmv9C6VUFvAmMAE4CTyita69FI10x5211lGSwv4SCAS+VEWwK4PX2NgoQ+5jx46xa9cuALZt28YzzzzDkiVLAGe1HrMoxOnTp7vVkHs8HgnTPPHEE1Ie4Gc/+xnl5eV9Nr51dXUEAoGLuqkNJG1tbRw9ehSAl156ib1797Jv3z4A9u/fL6GmwbrJGENtDLhxCIa7zt9i6Y7ehFCCwP/QWk8H5gHfVUpNB/4GWKe1LgTWRZ5bLBaLZZDo0V3TWpcBZZHHDUqpg8BoYAmwMPKxV4FPgB9dikYGg0GR8YVCIcmquxgVSl88P621eHChUEg8971797Jp0yZZDHn69OlMmzYNcBYV7sm7u+qqqwAnxGBUL5s2beLDDz/stTrDHEdjYyOBQEDkcYmJiUNaK0ZrLaGg/fv3c+bMGQkrtba2DmroQikloSXTL7YeuOVyoE/jbaXUBOBaYCuQFzHuAOU4IZZLQigUoqamBnDCKcnJyYATAx+KLDp3kSiv1yuyRnNjgZ416lprUWlkZ2eLsuWGG25g06ZNMsTv7bG1tLQQCASkDUlJScOm2Fd7e7vcgIcCI7GEL8okmExba8AtsUyvDbhSKgVYDjyvta53GwettVZKdWpplFLPAs9ebEPNhdbW1ibe6UDXA+8txvMfM2YM99xzjxjNY8eOcfz4caDnyTGfzyer22dkZMgNqqqqql8lAkwtcPO7+P3+Lg14x5uee5JvoAyax+ORePxQa63duQNer5dAICCTxnYS88uY87vDNR41uT9ixAhJ1KqsrBwWq1JdifQqBqGU8uEY72Va63ciL1copfIj7+cDlZ19V2v9W631HK31nIFosMVisVgceqNCUcArwEGt9c9cb60EngJejPxfcUlaiHP3N5l0bW1tnD9/HqDbu358fDzJyckSiggEAgPisSulmDRpEgAPPfQQCxYskHrS27Ztk0Sa7vajlGLkyJEUFRUBTpbgBx98ADhrbtbX1/e5nYmJiVErF/XkSXs8HqkhPnr06Chv6sKFC1Hf70vKv9lObm4u48ePB+Dzzz8ftIzLzoiLiyM9PR1wPPDGxkbrgXeBx+MRyezUqVMZM2YMANu3b+fcuXMSvlyyZIl87t133+X48eMDXjxNKSWjOI/HI+ekKSLnlvqax6FQ6IpKzOpNCOUG4Algn1Jqd+S1v8Ux3H9USn0LOAU8cmma6Bijw4cPA84KKqZqYHeV5Hw+H08//TR33XUX4MSIt2zZwsGDBwGnHoe5ATQ1NUWtYNPe3t5l5bxx48Zx3333AfDYY4+RlZUl8ri1a9f2apUgrTUNDQ0ijWxtbWX3bqdrOxrP3mwLHN11U1OTVE/Mzs7udpLX5/NRWFgIOKnuV199tex/3bp1/P73vwccg96XC8KEKm655RYWLlwIOPVjjh071m9j6T6O/ixS4V7gWWtNXFxcn+cYrhRSUlL46le/CsDSpUuZMmUKAB988AEfffQRBQUFADz55JNyHTY1NbFs2bIoqe9A4PP5JAN72rRpchP+9NNPKS8vFznx3Llz5cayadMmzp8/f8UsJ9gbFcpnQFezYbcNbHMsFovF0luGR9ZHLzBhiv379zN79myg+0Se1tZWiouLufXWWwFH3VFUVMSZM2cAOHz4sHjctbW1VFRUyDCsvr5evOrKykoSExOZPn06AIsXL+bGG28EoKCggObmZlkgd8+ePb2uee3OBgwEAhJ6MVK7vlYqbG1tpa2tTYo1paendzmJGRcXR05ODs899xwAX//61yWpKBwOM3nyZAmvvPrqq7L8WG/aYrykxYsXM2/ePMDxmMrKyjpdLLonlFLSNvjiPOiLN98xyxYY0trkw5mcnBwWLFgAwI033igF3mpra/F4PCKTnTp1qnxn3LhxUUv4DQRer5f8/HwZ7S5ZskRGd7m5uaxZs4YZM2YA8NRTT4k3npGRwerVq6+YEFnMGHBjbD///HOpctedTC4UCrF9+3ZJ5540aRIFBQUSv77hhhuiYmrNzc3yPBQKiaFob2+Pkufl5+eLZtvr9XL06FGJX9fU1MhNxZzM7jZ2HNaZYXxbW5tkJhrFRm8vBrN9E+M3Mejk5OQu+8fn87Fw4UK5uWVkZMiNo6KigvT0dP7iL/5C2rhs2TKgd9UWjRyyqKhILv6HH36YXbt2SRnevsRKExMTmTVrFgCzZ8/mrbfeApxiXb0NNQWDQRneh0IhUlJSJLY6XKSWw4Xz58+zdetWAHFUAHbs2MG6detEDpqXlydzUatXr+5XEbfuMPNEX/va1wC47rrr5Leqrq6mvr6eO++8E4CvfvWr4nCcOnWKffv2iarLGvBhgrngysvLOXfuHNBzvY+6ujop9RoMBnn88cclppeenh51ERvP0eCOtbrleR6PR2KywWAQpZTEDCdNmiTvlZWVRcVag8Eghw4dkve01nIjCAQC4uW2t7d/Sb7VHcYryc/PZ8SIEeJpNjQ0fOm75nhHjRrFI488wrhx4wBnlPHKK68A8NFHH1FYWMiPfuTkZD322GN8/PHHgOOF9SRx/MpXvgI4E6PmONra2vpVOVIpxahRo2QeY+HChXJjfeONNyQZpzfbMReyuTnaBZ87x10jKCkpidGjRwOOkT5y5AjHjh0DnHo2xoDv3LlzwCepw+EwpaWlfPrppwDMnDlT5pc2btzI0aNHZZL8+uuvlxvLnj17qKiouOwNt8FWI7RYLJYYJWY8cOP57dq1S1bO6QmtNadOnQLg97//PVu3bpVKgnPmzBGvu6CggDFjxshMdnJysoQivF5vl7H2uLg4CgoKJFQQCATEA29oaMDj8Ui4wOPxSFyupqaG1tZWmcVPSUmRglgZGRnU1taK515ZWSnDw46KEK/XKyGhCRMmkJ2dLR54d8kzfr9fFqoAx5t99dVXAacI1759+0TiuHTpUh544AHZvxk9dMXkyZPleM1Iafny5ZSXl/fZK4qLiyM7O1sWIJ4+fTpLly4F4LPPPuPIkSO9CqOEw2HxEEOhEGlpaVEF0a4Ub603aK3Fm125cqWEDmtqaggEAvKbfvTRR3JNmnN1IAmHw1RUVEjIrLq6Ws7tjRs3UlVVJfNGpaWlMjLbvn075eXlV0yGbcwYcEMwGOSTTz4BHGlgT0Ngc3E2NDSwd+9ekSN+/PHHZGZmAs4kzKRJk+Rkzc3NlQm4sWPHMmLECAlVuLMWwZEymvfcGOPsxhg3o1V13xgefvhhAG6++WZaW1vF8Dc1NcnJ2NDQQENDA2fPngWccJIxbnPnziUzM1PizCdPnvySYTLtHDduHLm5uVLe9dVXX5UbXXt7O+3t7fz5z38G4NFHH5WU/9dee63b0gUm5GH2tXPnTgA2b97caUinJ5KSkpg0aZIspuHz+aTvU1JSorTB3dGxze6yu521qeMEsrkpx8XFyfcuZwNhju3ChQtfqhrpLl98qWlvb5dz/Z133pF9m2vixIkTgGPczbne3Nw85It5DyY2hGKxWCwxSsx54I2NjXz++edA35dUc3teLS0tMhw8dOgQ8fHxMsmXkJAgYZGJEycyfvx48SyTk5Ml1JKRkRG1eK8plATOkm3hcFi8Xr/fL5lrqamppKamylJsoVBIQhrjxo2L8grdGWdmYQvj/YRCIZkINQk8xmPqTKVhPMmUlBT8fn9U7XK316K1loSniooKycbLyMggLi6uywxYrbX0RSgU4siRI4AzcuiPx5qQkEBGRoZUWKyoqGD16tVA5yOMrtBaR9XPiY+Pl3b2lOyUl5fH3XffDTgTs0ZeunPnTsrKyr4kT7zc6KimGuzjNL+xW+ViRlTmPVOY7Eok5gx4e3s7p0+fvujtuA2Ku0QsOCeIiVcfOnSIpKSkqFWAjFFOTU0lGAxKmr/f75eTKi8vj2AwKN9LSkoS1ceIESPIyMiQIWAoFOKmm24CnFh2YmKixL3NPsw2EhMToxQz7sJDVVVVlJaWAo6x62g03c+DwaDM6mdlZck+Ghsb0VrLzaW2tpacnBxpS0+LaJh9tLe3X3TFPzP/YIxGRUWFKGIuXLjQa2Pi1ty3t7fj9/ujUuu7YuLEiTz++OOigsnLyxO10Nq1a1m+fLkY9O7UOX1RFQ03TP/Ex8cTCoXkOPu6bqs7Jd5so6/nhZV8fpmYM+Du1VQu5T461v92x/zMidTZf3NimxPfLT80J7HX6yUnJycqqcSMKmbOnElGRoZ4iCNGjJAT3nijRmudnZ0t20hMTGTnzp1s2LABcCadOl4gZjvNzc20traKZ5mUlBTlcXu9XpkPGDVqlLQlJSWlRwNuPN1AICB9aGpV9Md4uSWAdXV1YkD7OvFo+iIQCOD1emXE0llJYvM7LVmyhPvvv1/mLtxJRaNGjWLMmDH88z//MwBHjhzpMvaqtZZRhMfjoaWl5ZKkeruNrWmLqRvSX4yM8KqrruLgwYOSCNeXipkpKSkyKZ6VlcWWLVuAzqWuXaGUEkcpIyMjStvfn+qdlws2Bm6xWCwxSsx54DA0w9C+Dvd68grq6uqi4oplZc7aGOvWrYuqrpaVlSWx/ry8PDIzM0U6mJubK5KvlpYWzp8/z549ewA6LarljqX7fD6ys7MBRwFjRjW1tbVRcwuTJk2StjU2Nvbo+ZrjVkpJzH/06NFR2a3uvuyobujoCfv9fgnnlJSUyOO+ngMdQwFdqUm8Xq94nXfddRcTJ06Uz2zZskWO4aqrruKOO+7gs88+A5yRi8n+66xtRr46a9YsVq9eLfMvA3Uujxo1iieffBJw+tuoij7++GOKi4v7lUjl9/u55pprAKfy5gcffCDnW28zLz0eD2PHjuWhhx4CnHPWhECPHj3a4/lkRn+ZmZncf//9gJMs1tTUxNq1awHYsGGDJHXFWojqYolJA345EAqFogy4CT20tLREDenr6urkcXl5OR6Ph82bNwNExYfj4uJob2+P0jt3RTAYJC4uTmLwo0aNEmNuwjJuCZ1JrS4rK+tWoqWUkuy8uLg4CdEUFRVRV1fHgQMH5DiMsWtubqa6ulrmHOrq6mQfcXFx+Hw+OaaysrJ+abY9Ho/UiElMTKS9vV0u+I7lR+Pj46Uy4+TJk4mPj+fDDz8E4PXXX5ds2vnz5/PMM89IxcXt27dLmK3jzVspxfz58wF44IEHCAQCvPfeewD9Kh3s3i44N/kf/vCHLF68GHDmKkz/Tp06lWXLlknYojcZk2a7ubm53HLLLYCTVl9VVcXevXsBx0HojVwvISGBKVOmyHYyMjKkFMbZs2e7zab1+XwiIX300Ucl/2PcuHEEAgGpjNjW1sbGjRt7fXyXEzaEYrFYLDGK9cCHCLes8MKFC1H1qd0embsOixn6dybj643My50Q1NLSIhOVP/nJTyQhaNq0aaSlpUnIoaSkhOXLlwNOmKAnr8uoMpqbm6VyXWFhIeFwWEIx9fX1EuIJBAK0traK17p+/Xrxxt3ZquB4Wu61LTseW8djN899Pp8sIJ2cnEwoFIqSFbrx+Xwyaen3+zly5Ahvv/024AzVTdvKysqYOnWqqIemTp1KSUkJ8GUP3OPxiLdYVFTE0qVLJdRVXFzc78QTo1S67777WLRokUhRW1tbZbL1zjvvJD4+XkIfBw4c6HF/5lzKycmREEpOTg4jR46Uc7a3C4qnpaVRUFAgMtzU1FQpTvZf//VfXXrgHo+HzMxMKbj28MMPS/36+Ph4tNZSg+jkyZNSo+X06dOXdZJVR6wBHwJSU1NZtGiRnJBbtmxh06ZNgDM0TUhIkDh3eXm5zLZ3d2L2Zhhuwg/19fW0trbKRVVXV8dLL70EOEWxRo4cKUqXvXv3SkGh3gz3jZrm2LFjYmTT09Oj9PPhcDhKheHe5owZMyTO3NTURF5ensgYb7/9djEg586di1K6HD9+XOK+586dQ2stBu6aa66RcgCpqamUlpaKxLFjSCYlJUWG7XV1dbz33nsyPK+qqhLjV1VVxb59+6Qi3pgxY+SGaKSYhoSEBJGQmhBCfn4+AAcPHuyXAfd4PPL7PfDAA+Tl5cl58vbbb0soa/78+cyZM0dCGGfOnOlx4QXTb/n5+dLOyspKtmzZItm7vW1zXl4eM2bMkL6prKyU36m7FbX8fj9TpkyRsNCECRPk88XFxdTV1UlJ29mzZ8sNurKyUuZJ+oM5Z2NlZR9rwC8xbs/YnMTf+c53WLx4sVzUt956Kz//+c8Bp5ra4sWLZdJn27ZtsjrO/v37L0oyZYxmaWkpp06dkv0/++yzfPe73wWQSnTmRG5ubhZvtTc1zs0F/sILL0gsubCwkOzsbJkcTEtLE1ldfHy8JDaBU5fGtNOMPoy3N2/ePNlmQ0NDlESuqqpKvMzq6moSExOlVEJSUpKMBpKSkmhpaelyRZ5AIBB1o9mzZ09UaVL3ZOv27dtlVDF16lRJ/qqpqYkycD6fL+qGFQgEOp3Q7QtaaxmdjBs3Dq/XK3VDfve738lIYfv27bzwwgsSP16/fr3suycjHAwGZRLx2LFj7Nq1S/q4t+0OhULk5ubKJOqBAwfYvn070PlEu8Hn8zFz5kwx0gkJCeLkvPLKK5w5c4brrrsOgEceeYTbb78dgN27d/eqxEZneDwemWyurKyMiaqGNgZusVgsMYr1wC8xbk/AXb3NxBTBufPPnTsXcIb7Dz74oNQtnzhxongBv/71rwckxtfU1MTBgweldve0adNkAYcXX3wxKk29r56MGeZu2bKFXbt2AY6XnZSUJN7UyJEjpQRAcnIyOTk5ErIpKCiQkUpaWhoNDQ3irY8cOVLUJEY1Y5g0aZK0ub29PWrRZneKP6Hj+jYAABWbSURBVDheqZHBdexLo9CBL+K15phKS0uluFJdXZ38gRMjNsfUMT7s8XiiPPdDhw6JlK6/Hp7WWuLqaWlpHD58WOYqDh48KCOMhoYGduzYIdmk06ZNkxIHfQndnDlzpkcVUmd4PB6SkpIkbPP55593mwxkRqxpaWl85StfkZBZa2urlFHYsGEDNTU1MspYsGCBnFujRo3qVztNW40nX1VVxYoVK4Z9mn6vDbhSygvsAEq11ouUUhOBN4BsYCfwhNa666DWFY5SSk6q5cuXi5YVnGHtypUrAceAueuy1NbWytCxL+nj3eHz+di6dSuPPOKsQx0fHy8a2z179vDGG29IDLW/dLaIgyn/GR8fL5ORxtCa47366qtlAi4vL4/KykoZ8s+ZM0eW0crMzCQuLk6MZVZWVpQU0uv1inH2eDxi0LZu3cqyZcvk4u/Yn4mJiVE1Yx588EFZmaaiokImKoPBIGPHjpX2lJSUdLlIhMfjkZIK4FRnNJLD/v6ecXFxMtmanJzMyy+/LBI/dwihsbGRzZs3y8o206dPF1lkV7FiY0R9Pp8Y2crKyqjKmD1htmHOZWPADx8+LOd9Z8du+j4jI4OpU6dK9qVSSm5CY8eOpaGhQYz7tGnTZJsjR47E5/P1y4CHw2E5Z++88062bdvW5Y1+uNCXEMp/Bw66nv8z8HOtdQFQC3xrIBtmsVgslu7plQeulBoD3Av8A/AD5dxebwW+GfnIq8ALwK8vQRsvC9zexrlz5/i7v/s7GQKfPHlSZuaLi4tJSEiQGtyrV6+W+ucd1Q39JRgMsmnTJvEmc3JyxJt5/vnnCQaDvPHGG8DAef3wRfXI7rIC3euKGg/QeFNbtmyRcEpycjJ+v188PVM10jx2e92NjY1UVlYCzkTw559/3mUbvF5vVDvD4bB42bNnz476XkJCgoRm9uzZ06VnqbWWEUZLSwvbtm276IST+Ph4+c3AOW+6UnWUlpZKX4wfPz4qnNQZpk/dlSfr6+ujlvvrqbCUexuAyAUrKyu79Y6NB56WlkZycrKMvvx+f1SY0WQTgzMxffToUSB6BNVXwuGwqKgeeughioqKJNltuCYI9TaE8i/AD4HUyPNs4ILW2vwSZ4HRA9y2yxZTjN7EU91lbgHefPNN3n//fcA58fubPt4VoVCIc+fO8c477wDOsNooNsaPH893vvMdGfJ++OGHgzqM7O5CaW1tFRVEx2JhR44cEcNkqkW61SyGpqambm8goVBIjE17ezslJSVSdnfq1Kki/TQVI81vU1xcLGqVjv3kTt2vqqrizJkz3S4o0RvcZYz9fj/f+ta3RLN9/PhxaVdaWhqzZs0SlU9ycnKPBs5dQtZdnM0sbgJOiMNUdDQljk17AoGAHF9+fj6JiYnSNybTGL4w7u4+MEY5MTGRQCAgWcBtbW2SzdoxRNbY2CjF2E6cOHFRSi1zTQYCAWbOnCkS2pg14EqpRUCl1nqnUmphX3eglHoWeLYfbbusCYVCXU5gmZV3LiXt7e28++67gKMjNt6Nz+djypQpMqmZmpoqk0cmlX2w9LHx8fEkJCTIxeO+ME3ijjEGLS0t3code1vPuqmpSSbZfD4fo0ePluNfv349CxYsABwvPz4+XhJyNm/e3KVev729XW48Y8eOjfIS+zuJGQgEovrlpptuklFbdXW1tMXr9ZKbmyuGNxAI9Og9mzZVVVWJkb3jjjsoKCiQ91JSUiSuHwgEaG5uFvllMBiUG0hiYiJ5eXny3hNPPCFJY1prLly4EOW8mLmXadOmkZycLLVm/vSnP1FcXAzAPffcw5gxY2QfW7du5fXXXwecG/nFGHAzN1JZWUlhYaH0W21t7bCUFPbGA78BWKyUugdIANKAXwAZSqm4iBc+Bijt7Mta698CvwVQSg1/ZbzFYrHECD0acK31j4EfA0Q88P+ptX5MKfUW8BCOEuUpYMUlbKflEmA8zR//+Mf8y7/8C+CoQHw+n6QpjxgxQjymFStWsH379k4TWwYS461NnTqVmTNnipd74MAB8a78fj+ZmZkSSikvL+82ttrbdgYCAUlGCofDFBYWSi3rP/zhD1IUKiEhgXA4HBUa6Soxpa2tTTzLlJQUCgsLRTHSX28xFArJ/tra2jh58iQTJkwAYMqUKVGjgLi4OImBm0SX7jDfNXFvgGuvvVayHcHx7N2efDgcFm89HA5HeauJiYniyX79618XaZ5SioaGhqjPmvcyMjLIz8+XkcrRo0clXX7VqlXk5uZK20pLS+U3u9h5ItM3DQ0NjB07VhRRHo8nZj3wrvgR8IZS6u+BXcArA9Mky2BhTsjt27fz3HPPAfD973+fO+64Q3TZM2bMkIzNKVOmsGrVKlk04uzZs5KJOFAnd0pKitww7r//fhYuXCjxzZ/+9KeyKPWsWbN45JFHRGb2k5/8hOPHjwN90zd3JBgMyoRYU1MTOTk5ki6/b98+0VobQ2FuIO7yAB0JhULSNoBbbrlFFo3ub9age9UkcHTp//7v/w44xtZIDBMTE2lsbJRY8rp167rNgDTHAo4xNdUXJ06cSFxcnLTVnc3q8/nkhgbROniv1xtVv8ct93Tvy+BeBMTj8UhcPyUlRfTrpaWlUdr6zurgXCzx8fGycPZwpk8GXGv9CfBJ5PFx4PqBb5LFYrFYeoPNxLQQCARkSP/iiy+yY8cOHn30UcDxwI2CYe7cuUyZMkUSKvbs2cMHH3wAwI4dOy6qtrXB4/HIIsq33XYbhYWFUsyqra2Njz76CHDqQ8+dO1c84LKyMv71X/8VcCbx+tuOUCgkSoQTJ04wevRoKSz2yCOPiCLFTJb1xtvXWktWam1tLTfddJMoKtasWdOjR9zVNs3yck1NTRQWFor0c/Xq1ZLlm52dTTgclt+3u6Xf3NsGZyLvl7/8JeCE21JTU+W9+vp6CXckJSVJFipE136Jj4+npqZGwm6FhYUyOjBZmm4v14QsgsEgWVlZErZZsGBBVDXLSxW+M0oaI/10r506HJduswbcAnwRdigpKaGmpkZ06UVFRVKk6dprr2X06NFiUK+//noxRP/0T//EmjVrLlpu1dzcLMZu7969+P1+STvfvHmz6LmNdt0MzUeOHCmqiJqamn5f3FprUQBt2LCBGTNmSDhp3rx5krH65ptvcvLkyV6Ha8xiFmfOnGHBggWi8jlz5oyU4DXyxt4qZkyop7q6mmuuuUZCPf/wD/8g8wbmBmekkYFAoNdy0EAgwI4dOwAnV8Fdwre9vV0MWnx8vMj/OuL1egmFQnJsqampUvY2HA6LJNBgqh+2tbXxla98RY7p6aeflhDK1q1b+7XCUE8opeRmnZmZicfjkbIOwzWUYg24JYpQKER1dbWs/r5jxw4xjAUFBRQWFkZN3JnHF1sp0RAMBiXB6LXXXqO4uFgM1YYNG2Qff/jDH4iPjxfPcuXKlTJReLF6dXNMa9eu5Y477hCvMC0tjW984xuAYxDfeust8YJ72qfxQI8cOcK8efMkPX/JkiUi+Tt16lSfFiE2I4XKykrC4TA333wz4MgdjazO3Mz6G2c3hrK0tFORWa9wG7+Kigq5IZsaNe7JUKPh11qzb98+Ke07e/ZsnnrqKcBJLjt8+LC0baA88fT09CiZqHt1qOHK8LytWCwWi6VHrAduicJ4ayYu29LSIskNZ8+eZfPmzeLxuL3F7hKT+opRN2zYsIEdO3ZIWMatuli+fDnHjh2TAlnuBY8vFnNMxcXFvP766+IVzpo1SySFf/3Xf016ejovv/wy4MgYu/PCjSe3Zs0aFixYILHdJ554QsJAr7/+OqdOner1SMb8LsXFxcyZM0dCPY8//riMYjZu3NjtupODgbtflFJR4Y+2trZOQ0ZKKfbt2yfqGffci6l9biSdA5Fkk5mZyYIFC7j33nsBp6rhoUOHZFQ3XD1xa8At3eK++EKhkBjXwaC5ublLo1xZWcmGDRvkwroUE0zNzc2sWrVK6q8kJCTIwhAFBQV8+9vflnj58uXLZaX57i72nTt3smvXLknJHzNmDI8//jjg3Cz/+Mc/9mo75vMAmzZt4u677xYDPmvWLImxNzQ0sGvXrl4vyjFQGKPs9/uZMGGChHuam5uj0vOzsrKkD9va2qLa19jYKJPW8+bNk2zhRYsWUVRUJPLS9evXS6y+rKyMpqYmuSl2VhnSXUPFaOeXLFnCLbfcIr9veXk5n332mYR7hqsBtyEUi8ViiVGsB26JScLh8CUvMBQOhyktLZXknebmZp5//nnAmeQaPXo03/72twFHFWPqbO/Zs4eGhoZOQyrV1dW89957srDv1VdfLcoH4zUbaeaJEyeiKgx29CbN9nfu3MnWrVtFfpmTkyOLAbe1tfHyyy9Llb2BqmjZEybzctGiRdx6661S0+Tjjz+WDOBZs2Zx4403iuJp48aNojIyITnT7vfee0+Ob8KECcyePZvp06cDcOONN0o4yRQKM4lTDQ0NMomqlGLEiBFRFS1NBcvCwkLS09NlUvr9999nw4YNfV5CbrCxBtxi6YZgMCjD//fff18kcPfddx9TpkyRlZOWLl0qiomVK1eya9cuUW40NzdLjDYUCrF161YpJJadnS2ZrgUFBTz33HNi/F5//XUpZ9rc3NzlML66upq3335byhPfeOONUl3yzjvvpK2tTfTNO3fulOqSlyo13Ov1Siz5e9/7HpMnT5a2ZWVlsX//fgAWL17M3LlzZR4jISFBbl5GmWPCK++8844c09KlS5kwYYLkJ6Smpoq2fNasWSilRKMeCASi5I+miiR8oUMHJwR39OhR2f8777xDSUlJtwsvDwesAbdYesAYzrKyMn7zm98AztJgixcvlpVu8vPzufvuuwGYOXMmu3fvllKk27ZtEylkc3MzNTU1sgBxbm4uixYtApxKhRMmTOCZZ54BHO/cfG7btm0cP36808WYjaf62muvSVtMLDc7O5t7771XDNWYMWPYvHkz4Gi7O8adB5rc3FySk5PlBlJdXS2LW99www1MmjRJtNbp6eldrmp07tw5li1bJo+/9rWvMW/ePMDJATDbN8fpliO6ZYpKqahJUzOhunHjRt5++22pvX/q1ClaW1uH/cr0NgZusVgsMYoazDuMLSdriXVMPDUxMTHK6164cKEoS9LS0mhraxMFzfHjxyXNf/PmzbS1tcmwfvLkyVK24N5772Xq1KlSjTEQCEhMuLS0lG3btkkhsYMHD4pCwswFmIzZJUuW8OyzTgn+adOm4ff7ZQ3OEydOsG7dOsBRzpSWlkpIpbW1dUDUPEop8bJ/8IMfcPvtt/Pee+8B8NZbb0li2F/91V9xyy23iBzwF7/4BTt37ow6Jjcm9JGdnU1RUZGMMoqKikTeWVRURFpamnjicXFxUYt/hEIhCcuUlpayceNGwKm0uWvXLol5D2bd+16yU2s9p+OL1oBbLP3E4/FIvLqgoECMSE5OjqxSA86Q30jezIrpZhjv9Xqlbsl1113H/fffz3XXXQd8sZoNOManvr5eJvwOHjwo4RyznJvZZm5urqSg33PPPcydO1eMu8fjkfjygQMH2L17t6TdHzx4kL179w6IVNTc6KZMmcL8+fMlbHPq1CkxqHPmzOHee+9l1apVgBOfN5r17iYNvV4vfr9fjHR2djajRo2S/SmlRFKZnJws+0tKSqKxsVGMtLuMQUlJCS0tLcN2spIuDLgNoVgsFkuMYj1wi+UiMF6vqYkNzrDdvQ5mMBiMUqF0llwCjoc4cuRI8eRnz54tKpeWlhbKy8ulpkptba0M/0+fPh2llvB4PLLg8YwZM7j55puZOXMm4EyUGo/f6/VSXl4uiUN79+7lN7/5jVT9GwjbEBcXR1pamoQt3CGa5ORk8vLyRLrX10xa9yjGhKSSkpLQWksYyh1C8fl8tLa2ygijpaVF9jkcKw12wIZQLJbhjsfjEUVFamqqhAnC4XCUKsJd7qAzJYm5Kfj9frKysiSkMHbsWNFPJyQkcPbsWUkXLy0tpbi4eMBKEvQG98LJA4m7gJZbheIu7DXMYtw9YQ24xRLrdDRGvcHj8YgXGh8fL3F145Ea792sJh9jhu1KwcbALRaL5XLCJvJYLDFEf7xj93qd7e3t/VoByDI8sR64xWKxxCjWgFssFkuMYg24xWKxxCiDHQM/DzRF/lu+YAS2TzrD9kvn2H7pnMu5X8Z39uKgyggBlFI7OpPDXMnYPukc2y+dY/ulc67EfrEhFIvFYolRrAG3WCyWGGUoDPhvh2Cfwx3bJ51j+6VzbL90zhXXL4MeA7dYLBbLwGBDKBaLxRKjDJoBV0rdpZQ6rJQ6ppT6m8Ha73BEKXVSKbVPKbVbKbUj8lqWUurPSqmjkf+ZQ93OS41S6ndKqUqlVLHrtU77QTn8MnL+7FVKzR66ll86uuiTF5RSpZHzZbdS6h7Xez+O9MlhpdSdQ9PqS49SaqxS6mOl1AGl1H6l1H+PvH5Fny+DYsCVUl7g/wB3A9OBpUqp6YOx72HMLVrra1yyp78B1mmtC4F1keeXO/8B3NXhta764W6gMPL3LPDrQWrjYPMffLlPAH4eOV+u0VqvAohcQ98AZkS+86vItXY5EgT+h9Z6OjAP+G7k+K/o82WwPPDrgWNa6+Na6wDwBrBkkPYdKywBXo08fhW4fwjbMihorTcANR1e7qoflgD/qR22ABlKqfzBaeng0UWfdMUS4A2tdZvW+gRwDOdau+zQWpdprT+PPG4ADgKjucLPl8Ey4KOBM67nZyOvXaloYI1SaqdS6tnIa3la67LI43Igb2iaNuR01Q9X+jn0vUgo4Heu8NoV2SdKqQnAtcBWrvDzxU5iDg03aq1n4wzzvquUusn9pnakQVe8PMj2g/BrYDJwDVAG/HRomzN0KKVSgOXA81rrevd7V+L5MlgGvBQY63o+JvLaFYnWujTyvxJ4F2fYW2GGeJH/lUPXwiGlq364Ys8hrXWF1jqktQ4D/8YXYZIrqk+UUj4c471Ma/1O5OUr+nwZLAO+HShUSk1USsXjTLysHKR9DyuUUslKqVTzGLgDKMbpj6ciH3sKWDE0LRxyuuqHlcCTEXXBPKDONXS+rOkQu30A53wBp0++oZTyK6Um4kzYbRvs9g0GyllL7hXgoNb6Z663ruzzxSzyean/gHuAI0AJ8L8Ga7/D7Q+YBOyJ/O03fQFk48yiHwXWAllD3dZB6IvXcUIC7Tgxym911Q+AwlEylQD7gDlD3f5B7JPXIse8F8cw5bs+/78ifXIYuHuo238J++VGnPDIXmB35O+eK/18sZmYFovFEqPYSUyLxWKJUawBt1gslhjFGnCLxWKJUawBt1gslhjFGnCLxWKJUawBt1gslhjFGnCLxWKJUawBt1gslhjl/wecWayvhd3wCQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 363 ms, sys: 115 ms, total: 478 ms\n",
      "Wall time: 232 ms\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "img = cv2.imread(dataset['train'][3], 0)\n",
    "img = cv2.bitwise_not(img)\n",
    "img = img[:, np.min(np.where(img > 0)[1]) - 50:]\n",
    "im = imresize(cv2.flip((img.astype(np.float32)/255.), 1), (image_height,\n",
    "                                                           image_width,\n",
    "                                                           image_channel))[:,:,0]\n",
    "im = elastic_transform(im, im.shape[1] * 5, im.shape[1] * 0.3, im.shape[1] * 0.0001)\n",
    "plt.imshow(im, cmap = 'gray')\n",
    "plt.title(train_labels[3])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 64840/64840 [15:17<00:00, 70.64it/s]\n"
     ]
    }
   ],
   "source": [
    "import tqdm\n",
    "train_X = []\n",
    "for img in tqdm.tqdm(dataset['train']):\n",
    "    img = cv2.imread(img, 0)\n",
    "    img = cv2.bitwise_not(img)\n",
    "    img = img[:, np.min(np.where(img > 0)[1]) - 50:]\n",
    "    im = imresize(cv2.flip((img.astype(np.float32)/255.), 1), (image_height,\n",
    "                                                           image_width,\n",
    "                                                           image_channel))[:,:,0]\n",
    "    im = elastic_transform(im, im.shape[1] * 5, im.shape[1] * 0.3, im.shape[1] * 0.0001)\n",
    "    train_X.append(im)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 16211/16211 [03:48<00:00, 70.96it/s]\n"
     ]
    }
   ],
   "source": [
    "test_X = []\n",
    "for img in tqdm.tqdm(dataset['test']):\n",
    "    img = cv2.imread(img, 0)\n",
    "    img = cv2.bitwise_not(img)\n",
    "    img = img[:, np.min(np.where(img > 0)[1]) - 50:]\n",
    "    im = imresize(cv2.flip((img.astype(np.float32)/255.), 1), (image_height,\n",
    "                                                           image_width,\n",
    "                                                           image_channel))[:,:,0]\n",
    "    im = elastic_transform(im, im.shape[1] * 5, im.shape[1] * 0.3, im.shape[1] * 0.0001)\n",
    "    test_X.append(im)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(64840, 64840)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(train_labels), len(train_X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(16211, 16211)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(test_labels), len(test_X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle\n",
    "\n",
    "with open('jawi-to-malay-dataset.pkl', 'wb') as fopen:\n",
    "    pickle.dump({'train_X': train_X, 'train_Y': train_labels,\n",
    "                'test_X': test_X, 'test_Y': test_labels}, fopen)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
